import akka.kernel.Bootable
import akka.actor.Actor
import akka.actor.ActorRef
import akka.actor.ActorSystem
import akka.actor.Props
import com.typesafe.config.ConfigFactory

class Manager extends Actor {
  var doneCount = 0
  var workers = Runtime.getRuntime().availableProcessors();
  var work : List[Any] = List()
  
  def receive = {
    case Work(start, end, length) => 
      {
        println("Got work")
	    val workSize = ((end - start) / workers);
	    
	    for (i <- 0 to workers - 1)
	    {
	      val w = context.system.actorOf(Props[Worker], name = "w" + i)
	      if (i == 0)
	      {
	    	w ! Work(start, (start + workSize), length)
	      }
		  else if (i == workers - 1)
		  {
		    w ! Work((start + (workSize * i) + 1), end, length)
		  }
	      else 
	      {
	        w ! Work((start + (workSize * i) + 1), start + (workSize * (i + 1)), length)
	      }
	    }
      }
    case Done(l) =>
      {
        doneCount = doneCount + 1
        work ++= l
        if (doneCount == workers)
        {
          work.foreach { println }
          val supervisor = context.system.actorSelection(Connections.server)
          supervisor ! Done(work)
          println("Done. Shuting Down")
          context.system.shutdown()
        }
      }
    case _ =>
      {
        println("Unknown msg received")
      }
  }
}

class Worker extends Actor {
  def receive = {
    case Work(start, end, length) => 
      {
        var l : List[Any] = List();
        var i = start
        while (i <= end)
        {
		    var sum : Long = 0;
		    var j = i;
		    while (j < (i + length))
		    {
		      sum = sum + (j * j)
		      j = j + 1;
		    }
		       
		    val result = Math.sqrt(sum).toLong
		    val sum2 = result * result 
		     
		    if (sum == sum2)
		    {
		      l :+= i
		    }
		    
		    i = i + 1
		}
        sender ! Done(l);
      }
  }
}

class WorkerApplication extends Bootable {
  val system = ActorSystem("WorkerApplication", ConfigFactory.load.getConfig("worker"))
    
  val manager = system.actorOf(Props[Manager], "Manager")

  def startup() {
  }

  def shutdown() {
    system.shutdown()
  }
}

object LocalWorker {
  def main(args: Array[String]) {
    new WorkerApplication
    println("worker started - waiting for work")
  }
}
